Passed
Push — master ( 3772d6...966d0d )
by Night
01:13
created

numberFuncs.toHexUInt   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
cc 2
eloc 4
c 1
b 1
f 1
nc 2
nop 2
dl 0
loc 5
rs 10
1
/** global: UB */
2
3
UB.intMaxValue = 2147483647;
4
UB.intMinValue = -2147483648;
5
UB.floatMaxValue = 3.40282e+038; /// 038 or 056? .. it was originally 038F
6
UB.floatMinValue = -3.40282e+038;
7
UB.doubleMaxValue =  9223372036854775807;
8
UB.doubleMinValue = -9223372036854775808;
9
10
UB.roman1s = ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"];
11
UB.roman10s = ["", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"];
12
UB.roman100s = ["", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"];
13
UB.roman1000s = ["", "m", "mm", "mmm", "mmmm", "", "", "", "", ""];
14
UB.roman = [UB.roman1s, UB.roman10s, UB.roman100s, UB.roman1000s];
15
16
UB.letterLegal = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "BB", "CC", "DD", "EE", "FF", "GG", "HH", "II", "JJ", "KK", "LL", "MM", "NN", "OO", "PP", "QQ", "RR", "SS", "TT", "UU", "VV", "WW", "XX", "YY", "ZZ", "AAA", "BBB", "CCC", "DDD", "EEE", "FFF", "GGG", "HHH", "III", "JJJ", "KKK", "LLL", "MMM", "NNN", "OOO", "PPP", "QQQ", "RRR", "SSS", "TTT", "UUU", "VVV", "WWW", "XXX", "YYY", "ZZZ", "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLL", "MMMM", "NNNN", "OOOO", "PPPP", "QQQQ", "RRRR", "SSSS", "TTTT", "UUUU", "VVVV", "WWWW", "XXXX", "YYYY", "ZZZZ", "AAAAA", "BBBBB", "CCCCC", "DDDDD", "EEEEE", "FFFFF", "GGGGG", "HHHHH", "IIIII", "JJJJJ", "KKKKK", "LLLLL", "MMMMM", "NNNNN", "OOOOO", "PPPPP", "QQQQQ", "RRRRR", "SSSSS", "TTTTT", "UUUUU", "VVVVV", "WWWWW", "XXXXX", "YYYYY", "ZZZZZ"];
17
UB.letterExcel = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ", "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ", "CA", "CB", "CC", "CD", "CE", "CF", "CG", "CH", "CI", "CJ", "CK", "CL", "CM", "CN", "CO", "CP", "CQ", "CR", "CS", "CT", "CU", "CV", "CW", "CX", "CY", "CZ", "DA", "DB", "DC", "DD", "DE", "DF", "DG", "DH", "DI", "DJ", "DK", "DL", "DM", "DN", "DO", "DP", "DQ", "DR", "DS", "DT", "DU", "DV", "DW", "DX", "DY", "DZ"];
18
19
UB.decZeros = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
20
UB.hexChars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
21
UB.toDegrees = (180 / Math.PI);
22
UB.toRadians = (Math.PI / 180);
23
24
UB.minOf3 = function(num1, num2, num3){
25
	if (num1 < num2) {
26
		if (num1 < num3) {
27
			return num1;
28
		}
29
		return num3;
30
	}
31
	if (num2 < num3) {
32
		return num2;
33
	}
34
	return num3;
35
};
36
UB.maxOf3 = function(num1, num2, num3){
37
	if (num1 > num2) {
38
		if (num1 > num3) {
39
			return num1;
40
		}
41
		return num3;
42
	}
43
	if (num2 > num3) {
44
		return num2;
45
	}
46
	return num3;
47
};
48
49
UB.minOf4 = function(num1, num2, num3, num4){
50
	if (num1 < num2) {
51
		
52
		// 1, 3, 4
53
		if (num1 < num3) {
54
			
55
			// 1, 4
56
			if (num1 < num4) {
57
				return num1;
58
			}
59
			return num4;
60
		}
61
		
62
		// 3, 4
63
		if (num3 < num4) {
64
			return num3;
65
		}
66
		return num4;
67
		
68
	}
69
	
70
	// 2, 3, 4
71
	if (num2 < num3) {
72
		
73
		// 2, 4
74
		if (num2 < num4) {
75
			return num2;
76
		}
77
		return num4;
78
	}
79
	
80
	// 3, 4
81
	if (num3 < num4) {
82
		return num3;
83
	}
84
	return num4;
85
};
86
UB.maxOf4 = function(num1, num2, num3, num4){
87
	if (num1 > num2) {
88
		
89
		// 1, 3, 4
90
		if (num1 > num3) {
91
			
92
			// 1, 4
93
			if (num1 > num4) {
94
				return num1;
95
			}
96
			return num4;
97
		}
98
		
99
		// 3, 4
100
		if (num3 > num4) {
101
			return num3;
102
		}
103
		return num4;
104
		
105
	}
106
	
107
	// 2, 3, 4
108
	if (num2 > num3) {
109
		
110
		// 2, 4
111
		if (num2 > num4) {
112
			return num2;
113
		}
114
		return num4;
115
		
116
	}
117
	
118
	// 3, 4
119
	if (num3 > num4) {
120
		return num3;
121
	}
122
	return num4;
123
};
124
125
/** calc overlap of 2 numeric ranges */
126
UB.overlap = function(value1Start, value1End, value2Start, value2End){
127
	
128
	// swap if reversed
129
	if (value1Start > value1End) {
130
		var temp = value1Start;
131
		value1Start = value1End;
132
		value1End = temp;
133
	}
134
	if (value2Start > value2End) {
135
		temp = value2Start;
136
		value2Start = value2End;
137
		value2End = temp;
138
	}
139
	
140
	// exit if no overlap
141
	if (value1End < value2Start || value2End < value1Start) {
142
		return 0;
143
	}
144
	
145
	// return overlap of 2 ranges
146
	if (value1Start >= value2Start && value1End <= value2End) {
147
		return (value1End - value1Start);
148
	} else if (value2Start >= value1Start && value2End <= value1End) {
149
		return (value2End - value2Start);
150
	} else if (value1Start < value2Start && value1End <= value2End) {
151
		return (value1End - value2Start);
152
	} else if (value2Start < value1Start && value2End <= value1End) {
153
		return (value2End - value1Start);
154
	}
155
	return 0;
156
};
157
158
// distance between 2 lat/lon coords
159
UB.latLonDistance = function(latitude1, longitude1, latitude2, longitude2){
160
	
161
	// all lat/lons are floating point numbers in degrees
162
	
163
	var theta = longitude1 - longitude2;
164
	var miles = (Math.sin(latitude1*UB.toRadians)*Math.sin(latitude2*UB.toRadians)) + (Math.cos(latitude1*UB.toRadians)*Math.cos(latitude2*UB.toRadians)*Math.cos(theta*UB.toRadians));
165
	miles = Math.acos(miles);
166
	miles = (miles * UB.toDegrees);
167
	
168
	miles = miles * 60 * 1.1515;
169
	var feet = miles*5280;
170
	var yards = feet / 3;
171
	var kilometers = miles*1.609344;
172
	var meters = kilometers*1000;
173
	return [miles, feet, yards, kilometers, meters];
174
};
175
	
176
177
var stringFuncs = {
178
	
179
	/** CONVERT LEGAL LETTER TO NUMBER .. A = 1, B = 2, C = 3  */
180
	legalNumeralToNumber: function(zeroBased){
181
		var s = this.toString();
182
		return UB.letterLegal.indexOf(s.toUpperCase()) + (zeroBased ? 0 : 1);
183
	},
184
	/** CONVERT EXCEL COLUMN ID TO NUMBER .. A = 1, B = 2, C = 3  */
185
	excelColumnToNumber: function(zeroBased = false){
186
		var s = this.toString();
187
		return UB.letterExcel.indexOf(s.toUpperCase()) + (zeroBased ? 0 : 1);
188
	},
189
	
190
	hexToDecimal: function(onlyDigits = 0){
191
		var hex = this.toString();
192
		hex = hex.toUpperCase();
193
		
194
		// remove prefix
195
		if (hex.indexOf("0X") === 0){
196
			hex = hex.substr(2);
197
		}else if (hex.charAt(0) == "#"){
198
			hex = hex.substr(1);
199
		}
200
		
201
		if (onlyDigits) {
202
			hex = hex.substr(0, onlyDigits);
203
		}
204
		return int("0x" + hex);
205
	},
206
	
207
	binaryToDecimal: function(){
208
		var bin = this.toString();
209
		var num = bin.toString();
0 ignored issues
show
Unused Code introduced by
The variable num seems to be never used. Consider removing it.
Loading history...
210
		bin = bin.toUpperCase();
211
		
212
		// remove prefix
213
		if (bin.indexOf("0B") === 0){
214
			bin = bin.substr(2);
215
		}
216
		
217
		var byte = 0;
218
		for (var i = 0, il = bin.length, il2 = bin.length - 1;i<il;i++){
219
			byte += uint(bin.charAt(il2 - i)) * Math.pow(2,i);
220
		}
221
		return byte;
222
	},
223
	
224
	none:null
225
};
226
227
// register funcs
228
UB.registerFuncs(String.prototype, stringFuncs);
229
230
231
232
var numberFuncs = {
233
	
234
	isOdd: function(){
235
		var val = this;
236
		return (val % 2) != 0;
237
	},
238
	isEven: function(){
239
		var val = this;
240
		return (val % 2) === 0;
241
	},
242
	isPositive: function(){
243
		var val = this;
244
		return (val > 0);
245
	},
246
	isNegative: function(){
247
		var val = this;
248
		return (val < 0);
249
	},
250 View Code Duplication
	relativeTo: function(v2, type){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
251
		var v1 = this;
252
		// type .. 0=any, 1=pos, 2=neg
253
		var v = v2 - v1;
254
		if (type == 1) {
255
			return v > 0 ? v : -v;
256
		}else if (type == 2) {
257
			return v > 0 ? -v : v;
258
		}
259
		return v;
260
	},
261
	abs: function(negative = false){
262
		var v = this;
263
		if (negative){
264
			return v > 0 ? -v : v;
265
		}
266
		return v > 0 ? v : -v;
267
	},
268
	acos: function(degrees = false){
269
		var v = this;
270
		if (degrees) {
271
			return Math.acos(v) * UB.toDegrees;
272
		}
273
		return Math.acos(v);
274
	},
275
	asin: function(degrees = false){
276
		var v = this;
277
		if (degrees) {
278
			return Math.asin(v) * UB.toDegrees;
279
		}
280
		return Math.asin(v);
281
	},
282
	atan: function(degrees = false){
283
		var v = this;
284
		if (degrees) {
285
			return Math.atan(v) * UB.toDegrees;
286
		}
287
		return Math.atan(v);
288
	},
289
	atan2: function(x, degrees = false){
290
		var y = this;
291
		if (degrees) {
292
			return Math.atan2(y, x) * UB.toDegrees;
293
		}
294
		return Math.atan2(y, x);
295
	},
296
	exp: function(){
297
		var v = this;
298
		return Math.exp(v);
299
	},
300
	log: function(){
301
		var v = this;
302
		return Math.log(v);
303
	},
304
	pow: function(power){
305
		var base = this;
306
		return Math.pow(base, power)
307
	},
308
	sin: function(degrees = false){
309
		var angle = this;
310
		if (degrees) {
311
			return Math.sin(angle * UB.toRadians);
312
		}
313
		return Math.sin(angle);
314
	},
315
	cos: function(degrees = false){
316
		var angle = this;
317
		if (degrees) {
318
			return Math.cos(angle * UB.toRadians);
319
		}
320
		return Math.cos(angle);
321
	},
322
	tan: function(degrees = false){
323
		var angle = this;
324
		if (degrees) {
325
			return Math.tan(angle * UB.toRadians);
326
		}
327
		return Math.tan(angle);
328
	},
329
	sqrt: function(){
330
		var v = this;
331
		return Math.sqrt(v);
332
	},
333
	compare: function(v2){
334
		var v1 = this;
335
		if (v1 < v2) {
336
			return -1;
337
		}
338
		if (v1 > v2) {
339
			return 1;
340
		}
341
		return 0;
342
	},
343
	positive: function(){
344
		var val = this;
345
		return val > 0 ? val : -val;
346
	},
347
	negative: function(){
348
		var val = this;
349
		return val > 0 ? -val : val;
350
	},
351
	
352
	exists: function(zeroOK = false){
353
		var v = this;
354
		if (zeroOK) {
355
			return (v != null && v == v);
356
		}
357
		return v != null && v == v && v != 0;
358
	},
359
	
360
	
361
	min: function(num2){
362
		var num1 = this;
363
		if (num1 < num2) {
364
			return num1;
365
		}
366
		return num2;
367
	},
368
	max: function(num2){
369
		var num1 = this;
370
		if (num1 > num2) {
371
			return num1;
372
		}
373
		return num2;
374
	},
375
	atMost: function(limit){
376
		var num = this;
377
		return num > limit ? limit : num;
378
	},
379
	atLeast: function(limit){
380
		var num = this;
381
		return num < limit ? limit : num;
382
	},
383
	
384
	
385
	isNear: function(target, near = 1){
386
		var val = this;
387
		return val >= (target - near) && val <= (target + near);
388
	},
389
	
390
391
	/** Render a percentage (25%) using 2 values */
392
	percentageToString: function(current, decimals = 0){
393
		var total = this;
394
		return ((current / total) * 100).roundToString(decimals) + "%";
395
	},
396
	
397
398
	// CONVERT TO ABBREVIATION .. 1.5K
399
	toAbbreviation: function(decimals = 1){
400
		var num = this;
401
		if (num < 0) {
402
			return "-" + (-num).toAbbreviation; // -5.2K, -5.2M ..
403
		}
404
		if (num < 1000) {
405
			return String(num); // 520
406
		}
407
		if (num < 1000000) {
408
			return (num / 1000).roundToDigits(decimals) + 'K'; // 5.2K
409
		}
410
		if (num < 1000000000) {
411
			return (num / 1000000).roundToDigits(decimals) + 'M'; // 5.2M
412
		}
413
		return (num / 1000000000).roundToDigits(decimals) + 'G'; // 5.2B
414
	},
415
	
416
	
417
	// CONVERT TO ROMAN
418
	toRomanNumeral: function(){
419
		var n = this;
420
		if (n < 1) {
421
			n = 1;
422
		}
423
		
424
		// exit quickly if single digit
425
		if (n <= 9) {
426
			return UB.roman1s[n];
427
		}
428
		
429
		// create roman number if longer
430
		var str = n.toString();
431
		var output = [];
432
		for (var n = 0, nl = str.length;n<nl;n++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable n already seems to be declared on line 419. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
433
			var series = ((nl - 1) - n);
434
			var charIndex = int(str.charAt(n));
435
			output.push(UB.roman[series][charIndex]);
436
		}
437
		return output.join("");
438
	},
439
	
440
	/** CONVERT TO LEGAL LETTER .. 1 = A, 2 = B, 3 = C .. AA, BB, CC */
441
	toLegalNumeral: function(){
442
		var n = this;
443
		if (n < 1) {
444
			n = 1;
445
		}
446
		return UB.letterLegal[n];
447
	},
448
	// CONVERT TO NORMAL LETTER .. A, B, C .. AB, AB, AC .. BA, BB, BC
449
	toLetterNumeral: function(){
450
		var n = this;
451
		if (n <= 26) {
452
			return UB.letterLegal[n];
453
		}
454
		return "?";
455
	},
456
	/** CONVERT TO EXCEL COLUMN ID .. 1 = A, 2 = B, 3 = C .. AA, AB, AC */
457
	toExcelColumn: function(zeroBased = false){
458
		var n = this;
459
		var min = zeroBased?0:1;
460
		if (n < min) {
461
			n = min;
462
		}
463
		return UB.letterExcel[zeroBased ? n : n-1];
464
	},
465
	
466
	// CONVERT TO ORDINAL FORMAT .. 1st, 2nd, 3rd
467
	toOrdinal: function(){
468
		var i = this;
469
		var j = i % 10;
470
		var k = i % 100;
471
		if (j == 1 && k != 11) {
472
			return i + "st";
473
		}
474
		if (j == 2 && k != 12) {
475
			return i + "nd";
476
		}
477
		if (j == 3 && k != 13) {
478
			return i + "rd";
479
		}
480
		return i + "th";
481
	},
482
	
483
	
484
	// OR
485
	or: function(returnVal, ifNull = 0){
486
		var n = this;
487
		if (n == ifNull) {
488
			return returnVal;
489
		}
490
		return n;
491
	},
492
	
493
	
494
	/** Calc padding for a given length */
495
	padding: function(multipleOf){
496
		var length = this;
497
		return (multipleOf - (length % multipleOf));
498
	},
499
	
500
	multipleOf: function(multipleOf){
501
		var value = this;
502
		return value + (multipleOf - (value % multipleOf));
503
	},
504
	
505
	
506
	// FROM C#
507
	
508
	distance: function(n2){
509
		var n1 = this;
510
		return Math.abs(n1 - n2);
511
	},
512
	
513
	/** Calc x % of the given value */
514
	percentage: function(percentWanted){
515
		var val100Percent = this;
516
		if (percentWanted == 100) {
517
			return val100Percent;
518
		}
519
		return val100Percent * (percentWanted / 100.0);
520
	},
521
	
522
	/** Calc the % of otherVal in relation to val100Percent */
523
	percentOf: function(otherVal){
524
		var val100Percent = this;
525
		return (otherVal / val100Percent) * 100.0;
526
	},
527
	
528
	/** Calc the difference between 2 numbers in %
529
	//  ... 100, 50 shows -50% difference
530
	//  ... 100, 150 shows 50% difference */
531
	percentDifference: function(otherVal){
532
		var val100Percent = this;
533
		return ((otherVal - val100Percent) / val100Percent) * 100.0;
534
	},
535
	
536
	isConsequetive: function(value, value2){
537
		return value2 == (value - 1) || value2 == (value + 1);
538
	},
539
	
540
	/** Returns the number halfway between the 2 given numbers
541
		Value1 can be greater than Value2. */
542
	between: function(value2){
543
		return this.middle(value2);
544
	},
545
	
546
	/** Returns the number halfway between the 2 given numbers
547
		Value1 can be greater than Value2. */
548
	middle: function(value2){
549
		var value1 = this;
550
		if (value1 > value2) {
551
			return value2 + ((value1 - value2) / 2);
552
		}
553
		return value1 + ((value2 - value1) / 2);
554
	},
555
	
556
	calcScale: function(targetValue){
557
		var value = this;
558
		if (targetValue === 0 && value === 0) {
559
			return 0;
560
		}
561
		return (value / targetValue);
562
	},
563
	
564
	ensure: function(defaultVal){
565
		var value = this;
566
		if (value === 0) {
567
			return defaultVal;
568
		}
569
		return value;
570
	},
571
	
572
	snapToHigher: function(snapBy){
573
		var val = this;
574
		return Math.ceil(val / snapBy) * snapBy;
575
	},
576
	snapToLower: function(snapBy){
577
		var val = this;
578
		return Math.floor(val / snapBy) * snapBy;
579
	},
580
	snapToNearest: function(snapBy){
581
		var val = this;
582
		return Math.round(val / snapBy) * snapBy;
583
	},
584
	
585
	toInt: function(round){
586
		var num = this;
587
		if (!round || round == "truncate") {
588
			return parseInt(num);
589
		}
590
		if (round == "round") {
591
			return Math.round(num);
592
		}
593
		if (round == "floor") {
594
			return Math.floor(num);
595
		}
596
		if (round == "ceiling") {
597
			return Math.ceil(num);
598
		}
599
		return 0;
600
	},
601
	
602
	/**
603
	 * Formats a Number adding commas and the specified decimal digits.
604
	 * Supports the million/billion and lakh/crore system.
605
	 * 
606
	 * @param	system					"million" or "lakh"
607
	 * @param	decimals				-1 = keep exact decimals as number, 0 = no decimals, 1+ = specific decimals
608
	 * @param	alwaysShowDecimal		add decimal even if decimal part is 0
609
	 */
610
	formatNumber: function(system, decimals = -1, alwaysShowDecimal = false){
611
		var num = this;
612
		
613
		var commas = system == "lakh" ? 2 : 3;
614
615
		// test if number is negative
616
		var neg = false;
617
		if (num < 0) {
618
			neg = true;
619
			num = -num;
620
		}
621
		// get the left number
622
		var numStr = String(num);
623
		var hasDot = numStr.indexOf(".")>-1;
624
		if (hasDot) {
625
			var parts = numStr.split(".");
626
			var whole = parts[0];
627
			var decimal = parts[1];
628
		}else{
629
			whole = numStr;
630
			decimal = null;
631
		}
632
		
633
		// if at least 4 digits
634
		if (whole.length > 3) {
635
			
636
			// extract 3 digits first 
637
			var wholeRight3 = whole.substr(whole.length - 3, 3);
638
			whole = whole.substr(0, whole.length - 3);			
639
			
640
			// add million / crore seperators
641
			if (whole.length < commas) {
642
				whole = whole + "," + wholeRight3;
643
			}else {
644
				var thou = "";
645
				var rem = whole.substr(0, int(whole.length % commas));
646
				var l = ((int(whole.length / commas)*commas) - commas) + (whole.length % commas);
647
				for (var c = 0;l >= 0;l -= commas, c++){
0 ignored issues
show
Unused Code introduced by
The loop variable c is initialized by the loop but not used in the test. Consider using another type of loop if this is the intended behavior.
Loading history...
648
					thou = whole.substr(l, commas) + (c === 0 ? "" : ",") + thou;
649
				}
650
				whole = (rem == "" ? "" : rem + ",") + thou + "," + wholeRight3;
651
			}
652
		}
653
		
654
		// return with or without dot
655
		var result = whole;
656
		if (hasDot) {
657
			if (decimals > 0) {
658
				//  4.200
659
				result = whole + "." + decimal.substr(0, decimals).padRight("0", decimals);
660
			}else if (decimals === 0) {
661
				//  4
662
				result = whole;
663
			}else if (decimals === -1) {
664
				//  4.2
665
				result = whole + "." + decimal;
666
			}
667
			
668
		}else if (alwaysShowDecimal && decimals > 0) {
669
			
670
			//  4.0000
671
			result = whole + "." + decimals.repeat("0");
672
		}else {
673
			
674
			//  4
675
			result = whole;
676
		}
677
		return (neg ? "-" + result : result);
678
	},
679
	
680
	ensureNotNaN: function(instead = 0){
681
		var val = this;
682
		if (val != val) { /// fast isNaN check
683
			return instead;
684
		}
685
		return val;
686
	},
687
	
688
	isNaN: function(){
689
		var val = this;
690
		return val != val || isNaN(val);
691
	},
692
	
693
	isAny: function(haystacks, asInt = false, fractionalDigits = -1){
694
		var needle = this;
695
		
696
		// return true if any haystack equals the needle
697
		for (var s = 0, sl = haystacks.length;s<sl;s++){
698
			var num = haystacks[s];
699
			
700
			// simplify value for comparison
701
			if (asInt) {
702
				num = int(num);
703
			}else if(fractionalDigits != -1) {
704
				num = num.roundToDigits(fractionalDigits);
705
			}
706
			
707
			if (needle == num) {
708
				return true;
709
			}
710
		}
711
		return false;
712
	},
713
	
714
	scale: function(inputMin, inputMax, outputMin, outputMax, outputLimit = true, outputFlip = false){
715
		var input = this;
716
		
717
		// ensure input within limits
718
		if (input < inputMin) {
719
			input = inputMin;
720
		}
721
		if (input > inputMax) {
722
			input = inputMax;
723
		}
724
		
725
		// convert input to %
726
		var percent = ((1*(input - inputMin)) / (inputMax - inputMin));
727
		
728
		// convert % to output
729
		var output = (percent*(outputMax - outputMin)) + outputMin;
730
		
731
		// ensure output within limits
732
		if (outputLimit){
733
			if (output < outputMin) {
734
				output = outputMin;
735
			}
736
			if (output > outputMax) {
737
				output = outputMax;
738
			}
739
		}
740
		
741
		// flip output
742
		if (outputFlip) {
743
			output = ((outputMax - outputMin) - (output - outputMin)) + outputMin;
744
		}
745
		
746
		// return scaled, limit-checked output
747
		return output;
748
	},
749
	smartScale: function(inputMin, inputMax, outputMin, outputMax){
750
		var input = this;
751
		if (inputMin > inputMax) {
752
			if (outputMin > outputMax) {
753
				return input.flipWithin(inputMin, inputMax).scale(inputMax, inputMin, outputMax, outputMin, true, true);
754
			}
755
			return input.flipWithin(inputMin, inputMax).scale(inputMax, inputMin, outputMin, outputMax);
756
		}
757
		if (outputMin > outputMax) {
758
			return input.scale(inputMin, inputMax, outputMax, outputMin, true, true);
759
		}
760
		return input.scale(inputMin, inputMax, outputMin, outputMax);
761
	},
762
	
763
	flipWithin: function(min, max){
764
		var input = this;
765
		if (max < min) {
766
			return ((min - max) - (input - max)) + min;
767
		}
768
		return ((max - min) - (input - min)) + min;
769
	},
770
	
771
	limitToDigits: function(digits){
772
		var input = this;
773
		return parseFloat(input.toString().substr(0, digits));
774
	},
775 View Code Duplication
	limit: function(min, max){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
776
		var input = this;
777
		
778
		// ensure ok
779
		if (input != input) { /// fast isNaN check
780
			return min;
781
		}
782
		
783
		// flip limits if in reverse order
784
		if (min > max) {
785
			var temp = max;
786
			max = min;
787
			min = temp;
788
		}
789
		
790
		// ensure within limits
791
		if (input < min) {
792
			return min;
793
		}else if (input > max) {
794
			return max;
795
		}
796
		return input;
797
	},
798
	limitToArray: function(array, extraMax = 0, extraMin = 0){
799
		var pointer = this;
800
		if (pointer <= -extraMin) {
801
			return -extraMin;
802
		}
803
		var last = (array.length + extraMax) - 1;
804
		if (last === -1) {
805
			return -extraMin;
806
		}else if (pointer > last) {
807
			return last;
808
		}
809
		return pointer;
810
	},
811
	
812
	wrap: function(min, max){
813
		var value = this;
814
		value -= min;
815
		var diff = (max - min) + 1;
816
		while (value < 0) {
817
			value += diff;
818
		}
819
		return min + (value % diff);
820
	},
821 View Code Duplication
	wrap2: function(min, max){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
822
		var input = this;
823
		
824
		// flip limits if in reverse order
825
		if (min > max) {
826
			var temp = max;
827
			max = min;
828
			min = temp;
829
		}
830
		
831
		// ensure wrapped to limits
832
		var diff = (max - min) + 1;
833
		while (input < min) {
834
			input += diff;
835
		}
836
		while (input > max) {
837
			input -= diff;
838
		}
839
		return input;
840
	},
841
	wrapToMax: function(max){
842
		var value = this;
843
		var diff = max + 1;
844
		while (value < 0) {
845
			value += diff;
846
		}
847
		return value % diff;
848
	},
849
	
850
	/** Identical to modulo operator, except negative values are also supported, and brought into positive range.
851
		Value will never reach limit, just like the modulo operator.
852
		Simpler than `wrap` which takes `min` and `max`. */
853
	modulo: function(limit){
854
		var input = this;
855
		
856
		// ensure wrapped to limits
857
		while (input < 0) {
858
			input += limit;
859
		}
860
		while (input >= limit) {
861
			input -= limit;
862
		}
863
		return input;
864
	},
865
	
866
	roundToDigits: function(decimals = 4){
867
		var input = this;
868
		
869
		if (decimals <= 0) {
870
			return Math.round(input);
871
		}
872
		
873
		// Returns a number rounded to specified number of decimals
874
		var multiplier = Math.pow(10, decimals);
875
		return Math.round(input*multiplier)/multiplier;
876
	},
877
	roundToString: function(decimals){
878
		var input = this;
879
		
880
		// Returns a number rounded to specified number of decimals
881
		// Add zeros to always return those many decimals
882
		var num = RoundTo(input, decimals).toString();
883
		if (decimals <= 0) {
884
			return num;
885
		}
886
		var add0 = 0;
887
		if (num.lastIndexOf(".") === -1){
888
			num = num+".";
889
			add0 = decimals;
890
		}else{
891
			add0 = decimals - ((num.length - num.lastIndexOf(".")) - 1);
892
		}
893
		while(add0 > 0){
894
			num = num+"0";
895
			add0 --;
896
		}
897
		return num;
898
	},
899
	
900
	
901
	// CHECKS
902
	/** Checks if the value is within min and max (supporting inclusive/exclusive modes) */
903
	isWithin: function(min, max, inclusive = true){
904
		var num = this;
905
		if (inclusive) {
906
			if (min > max) {
907
				return (num >= max && num <= min);
908
			}
909
			return (num >= min && num <= max);
910
		}
911
		
912
		if (min > max) {
913
			return (num > max && num < min);
914
		}
915
		return (num > min && num < max);
916
	},
917
	isWithinArray: function(arr){
918
		var slot = this;
919
		
920
		// no, if array empty / index negative / index more than last slot
921
		var len = arr.length;
922
		if (len === 0 || slot < 0 || slot >= len) {
923
			return false;
924
		}
925
		
926
		// else yes
927
		return true;
928
	},
929
	/** Checks if the value is > min and < max */
930
	isBetween: function(min, max){
931
		var num = this;
932
		return (num > min && num < max);
933
	},
934
	isOutside: function(min, max, inclusive = true){
935
		var num = this;
936
		if (inclusive) {
937
			return num <= min || num >= max;
938
		}
939
		return num < min || num > max;
940
	},
941
	isFractional: function(){
942
		var num = this;
943
		return int(num) != num;
944
	},
945
	isInteger: function(){
946
		var num = this;
947
		return int(num) == num;
948
	},
949
	
950
	
951
	// HEX
952
	toHex: function(digits = 6, withHash = true){
953
		var num = this;
954
		var zeros = ("0000000000000000000000000000000000").substr(0, digits - 1);
955
		return ((withHash ? "#" : "") + (zeros + num.toString(16).toUpperCase()).substr( -digits));
956
	},
957
	
958
	incrementWithin: function(min, max){
959
		var num = this;
960
		num++;
961
		if (num > max) {
962
			return min;
963
		}
964
		return num;
965
	},
966
	decrementWithin: function(min, max){
967
		var num = this;
968
		num--;
969
		if (num < min) {
970
			return max;
971
		}
972
		return num;
973
	},
974
	
975
	
976
	decimalToBinary: function(digits = 8){
977
		var num = this;
978
		var zeros = UB.decZeros.substr(0, digits - 1);
979
		return (zeros + num.toString(2)).substr( -digits);
980
	}, 
981
	decimalToBinary2: function(digits = 8){
982
		var byte = this;
983
		var bin = '';
984
		for (var i = 0;i<digits;i++){
985
			bin += String((byte & (0x80 >> i)) >> (7 - i));
986
		}
987
		return bin;
988
	},
989
	
990
	
991
	
992
	// MISC MATH
993
	pad: function(length, addToEnd = false, padChar = '0'){
994
		var number = this;
995
		
996
		// num to text
997
		var result = String(number);
998
		
999
		// exit quickly if already reached target len
1000
		if (result.length >= length) {
1001
			return result;
1002
		}
1003
		
1004
		
1005
		// pad
1006
		if (addToEnd) {
1007
			while (result.length < length){
1008
				result = result + padChar;
1009
			}
1010
		}else {
1011
			while (result.length < length){
1012
				result = padChar + result;
1013
			}
1014
		}
1015
		
1016
		
1017
		return result;
1018
	},
1019
	interpolate: function(min, max){
1020
		var progress = this;
1021
		// progress = (0 to 1)
1022
		/*return( (1 - progress) * min + progress * max ); <---- WHAT IS THIS??? */ 
1023
		return min + ((max - min) * progress);
1024
	},
1025
	hypot: function(b){
1026
		var a = this;
1027
		// sqrt(a^2 + b^2) without under/overflow.
1028
		
1029
		var r;
1030
		var aAbs = (a > 0 ? a : -a);
1031
		var bAbs = (b > 0 ? b : -b);
1032
		if (aAbs > bAbs) {
1033
			r = b/a;
1034
			r = aAbs*Math.sqrt(1+r*r);
1035
		} else if (b != 0) {
1036
			r = a/b;
1037
			r = bAbs*Math.sqrt(1+r*r);
1038
		} else {
1039
			r = 0.0;
1040
		}
1041
		return r;
1042
	},
1043
	apow: function(value){
1044
		var pow = this;
1045
		// input:	1,2,4,8,16,32,64
1046
		// output:	1,2,3,4,5,6,7
1047
		if (value == 1 || value === -1) return value;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
1048
		var count = 0;
1049
		while (value != 0) {
1050
			//remainder = value % pow;
1051
			value = value / pow;
1052
			count++;
1053
		}
1054
		return count;
1055
	},
1056
	invert: function(){
1057
		var value = this;
1058
		// input:	0.1		0.5		1 	2 		8
1059
		// output:	10		2		1	0.5		0.2
1060
		return 1 / value;
1061
	},
1062
	powAbs: function(exponent){
1063
		var x = this;
1064
		// This function always returns a positive value that conforms to the expected Exponent curve.
1065
		// Math.pow: If x is negative, and exponent is not an integer, returns NaN.
1066
		if( x >= 0 ) {
1067
			return Math.pow( x, exponent );
1068
		}
1069
		return Math.pow(-x, 1/exponent);
1070
	},
1071
	
1072
	// count digits in number
1073
	getWhole: function(){
1074
		var val = this;
1075
		
1076
		// -10.235 has 2 whole digits
1077
		return int(val);
1078
	},
1079
	setWhole: function(newval){
1080
		var val = this;
1081
		return newval + GetFractional(val);
1082
	},
1083
	getFractional: function(){
1084
		var val = this;
1085
		
1086
		// -10.235 has 3 fractional digits
1087
		var s = (val < 0 ? -val : val).toString();
1088
		var i = s.indexOf(".");
1089
		return (i === -1) ? int(val) : int(s.substr(i + 1));
1090
	},
1091
	setFractional: function(fraction){
1092
		var val = this;
1093
		return Number((parseInt(val).toString()) + "." + fraction.toString());
1094
	},
1095
	
1096
	
1097
	
1098
	// SLOT INDEX
1099
	minIndex: function(index2){
1100
		var index1 = this;
1101
		if (index1 <= -1) {
1102
			return index2;
1103
		}
1104
		if (index2 <= -1) {
1105
			return index1;
1106
		}
1107
		if (index1 < index2) {
1108
			return index1;
1109
		}
1110
		return index2;
1111
	},
1112
	maxIndex: function(index2){
1113
		var index1 = this;
1114
		if (index1 <= -1) {
1115
			return index2;
1116
		}
1117
		if (index2 <= -1) {
1118
			return index1;
1119
		}
1120
		if (index1 > index2) {
1121
			return index1;
1122
		}
1123
		return index2;
1124
	},
1125
	
1126
	
1127
	
1128
	none:null
1129
};
1130
1131
// register funcs
1132
UB.registerFuncs(Number.prototype, numberFuncs);
1133
1134